package com.dctp.ems.controller;

import com.dctp.common.cache.ContractCache;
import com.dctp.common.controller.BaseController;
import com.dctp.common.utils.DateUtil;
import com.dctp.common.utils.NumberUtil;
import com.dctp.common.vo.JsonResult;
import com.dctp.common.vo.PageResult;
import com.dctp.ems.config.OpsLog;
import com.dctp.ems.interceptor.OpsLogInterceptor;
import com.jfinal.aop.Before;
import com.jfinal.core.Path;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Path("/contract")
public class ContractController extends BaseController {

    /**
     * GET /contract/list
     * 分页查询合约
     */
    public void list() {
        int page = getInt("currentPage", 1);
        int pageSize = getInt("pageSize", 10);
        String symbol = getPara("symbol", "");
        Integer futuresId = getParaToInt("futures_id");
        String status = getPara("status", "");
        StringBuilder where = new StringBuilder(" WHERE c.deleted=0 ");
        List<Object> params = new ArrayList<>();
        if (StrKit.notBlank(symbol)) {
            where.append(" AND c.symbol LIKE ? ");
            params.add('%' + symbol + '%');
        }
        if (futuresId != null) {
            where.append(" AND c.futures_id = ? ");
            params.add(futuresId);
        }
        if (StrKit.notBlank(status)) {
            where.append(" AND c.status = ? ");
            params.add(status);
        }
        String select = "SELECT c.*, f.name AS futures_name ";
        String from = "FROM dctp_contract c LEFT JOIN dctp_futures f ON c.futures_id = f.id" + where + " ORDER BY c.status DESC, c.id DESC";
        var p = Db.paginate(page, pageSize, select, from, params.toArray());
        renderJson(JsonResult.successWithData(
            new PageResult<>(p.getList(), p.getTotalRow(), pageSize, page)
        ));
    }

    /**
     * POST /contract/add
     * 添加合约
     */
    @Before(Tx.class)
    public void add() {
        Record body = jsonBody();
        if (StrKit.isBlank(body.getStr("symbol"))) {
            renderJson(JsonResult.failWithMessage("合约编码不能为空"));
            return;
        }
        if (!checkDecimalParams(body)) {
            renderJson(JsonResult.failWithMessage("保证金/服务费参数不合法或为负数"));
            return;
        }
        // 检查唯一
        Long exist = Db.queryLong("SELECT id FROM dctp_contract WHERE symbol=? AND deleted=0", body.getStr("symbol"));
        if (exist != null) {
            renderJson(JsonResult.failWithMessage("合约编码已存在"));
            return;
        }
        body.set("create_time", DateUtil.now())
            .set("deleted", 0);
        if (!Db.save("dctp_contract", body)) {
            throw new RuntimeException("新增合约失败");
        }
        renderJson(JsonResult.success());
    }

    /**
     * POST /contract/update/:id
     * 更新合约
     */
    @Before({Tx.class, OpsLogInterceptor.class})
    @OpsLog(module = "合约管理",
            action = "合约修改",
            table = "dctp_contract",
            fields = {"fixed_margin","fixed_service_fee","status"})
    public void update() {
        Integer id = getParaToInt(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        Record body = jsonBody();
        if (body.getColumns().isEmpty()) {
            renderJson(JsonResult.failWithMessage("无有效字段"));
            return;
        }
        if (!checkDecimalParams(body)) {
            renderJson(JsonResult.failWithMessage("保证金/服务费参数不合法或为负数"));
            return;
        }
        // 检查 code 唯一（如果修改了code）
        String newSymbol = body.getStr("symbol");
        if (StrKit.notBlank(newSymbol)) {
            Record old = Db.findById("dctp_contract", id);
            if (old == null || old.getInt("deleted") == 1) {
                renderJson(JsonResult.failWithMessage("记录不存在"));
                return;
            }
            if (!newSymbol.equals(old.getStr("symbol"))) {
                Long exist = Db.queryLong("SELECT id FROM dctp_contract WHERE symbol=? AND id<>? AND deleted=0", newSymbol, id);
                if (exist != null) {
                    renderJson(JsonResult.failWithMessage("合约编码已存在"));
                    return;
                }
            }
            setAttr("oldRecord",old);
        }

        Object copy = body.get("copy");
        if (null == copy) {
            body.set("id", id)
                    .set("update_time", DateUtil.now());
            boolean updated = Db.update("dctp_contract", body);
            if (!updated) {
                renderJson(JsonResult.failWithMessage("更新失败或记录不存在"));
                return;
            }
            // 更新成功后，清除缓存
            ContractCache.delete(id.longValue());
        }else {
            body.remove("copy");
            body.set("id", null);
            body.set("status",0);
            body.set("update_time", DateUtil.now());
            body.set("create_time", DateUtil.now());
            if (!Db.save("dctp_contract", body)) {
                renderJson(JsonResult.failWithMessage("复制失败"));
            }
        }
        //删除缓存

        ContractCache.deleteBySymbol(newSymbol);
        renderJson(JsonResult.success());
    }

    /**
     * POST /contract/delete/:id
     * 逻辑删除合约
     */
    @Before(Tx.class)
    public void delete() {
        Integer id = getParaToInt(0);
        if (id == null) {
            renderJson(JsonResult.failWithMessage("参数缺失"));
            return;
        }
        int r = Db.update("UPDATE dctp_contract SET deleted=1, update_time=? WHERE id=? AND deleted=0", DateUtil.now(), id);
        if (r == 0) {
            renderJson(JsonResult.failWithMessage("删除失败或记录不存在"));
        } else {
            renderJson(JsonResult.success());
        }
    }

    /**
     * GET /contract/all
     * 获取所有启用状态的合约
     */
    public void all() {
        List<Record> list = Db.find("SELECT id, symbol,name, futures_id FROM dctp_contract WHERE status = 1 AND deleted=0 ORDER BY id DESC");
        renderJson(JsonResult.successWithData(list));
    }


    public void statList() {
        List<Record> list = Db.find("SELECT id, symbol,name FROM dctp_contract WHERE status = 1 AND deleted=0 ");
        for  (Record record : list) {
            renderJson(JsonResult.successWithData(record));
        }
    }

    // 校验数值参数合法且非负
    private boolean checkDecimalParams(Record body) {
        String[] keys = {"fixed_margin", "margin_ratio", "fixed_service_fee", "service_fee_ratio"};
        for (String key : keys) {
            Object v = body.get(key);
            if (!NumberUtil.isValidDecimal(v)) return false;
            if (v != null) {
                try {
                    if (new BigDecimal(v.toString()).compareTo(BigDecimal.ZERO) < 0) return false;
                } catch (Exception e) {
                    return false;
                }
            }
        }
        return true;
    }
}
